// 三段式Moore状态机

// 模块及端口声明
module 1_2_fsm_flowingLED
#(
	parameter CNT_MAX = 	25'd24_999_999  //设定cnt可达最大值
) 

  ( input sys_clk,
	input sys_rst_n,
	
	output reg [3:0] led
   );
	
// 寄存器定义	
	reg [3:0] c_state;                       // 现态寄存器
	reg [3:0] n_state;                       // 次态寄存器
	reg [24:0] cnt;                          // 计数器
 
// 状态机参数定义	
	localparam                               // led状态
		l_0 = 4'b0001,						 
		l_1 = 4'b0010,
		l_2 = 4'b0100,
		l_3 = 4'b1000;
			
//计时模块
always@(posedge sys_clk or negedge sys_rst_n)begin
		if(!sys_rst_n)
			cnt <= 25'b0;
		else if(cnt == CNT_MAX)begin  
			cnt <= 25'b0;
			end
		else
			cnt <= cnt + 1'b1;
	end

//状态机第一段：同步时序描述状态跳转
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
		c_state <= l_0;
	else
		c_state <= n_state;
	end 

//状态机第二段：组合逻辑进行跳转条件判断
always@(*)begin
		case(c_state)
			l_0:  begin  if(cnt == CNT_MAX )  n_state=l_1;  else n_state=l_0;   end
			l_1:  begin  if(cnt == CNT_MAX )  n_state=l_2;  else n_state=l_1;   end
			l_2:  begin  if(cnt == CNT_MAX )  n_state=l_3;  else n_state=l_2;   end
			l_3:  begin  if(cnt == CNT_MAX )  n_state=l_0;  else n_state=l_3;   end
			default: n_state<=l_0;	
		endcase
	end

//状态机第三段：时序逻辑描述状态输出
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)
			led <= 4'b1110;
	else
		case(c_state)
			l_0:led <= 4'b1110;       
			l_1:led <= 4'b1101;
			l_2:led <= 4'b1011;
			l_3:led <= 4'b0111;
			default:led <= 4'b1110;         
		endcase
	end

endmodule 
